// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Serverless.Fluent;
using Elastic.Clients.Elasticsearch.Serverless.Serialization;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Serverless.Security;

internal sealed partial class QueryRoleConverter : JsonConverter<QueryRole>
{
	public override QueryRole Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		if (reader.TokenType != JsonTokenType.StartObject)
			throw new JsonException("Unexpected JSON detected.");
		IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.ApplicationPrivileges>? applications = default;
		IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.ClusterPrivilege>? cluster = default;
		string? description = default;
		IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.IndicesPrivileges>? indices = default;
		IReadOnlyDictionary<string, object>? metadata = default;
		string name = default;
		IReadOnlyCollection<string>? runAs = default;
		IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.FieldValue>? sort = default;
		IReadOnlyDictionary<string, object>? transientMetadata = default;
		while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
		{
			if (reader.TokenType == JsonTokenType.PropertyName)
			{
				var property = reader.GetString();
				if (property == "applications")
				{
					applications = JsonSerializer.Deserialize<IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.ApplicationPrivileges>?>(ref reader, options);
					continue;
				}

				if (property == "cluster")
				{
					cluster = JsonSerializer.Deserialize<IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.ClusterPrivilege>?>(ref reader, options);
					continue;
				}

				if (property == "description")
				{
					description = JsonSerializer.Deserialize<string?>(ref reader, options);
					continue;
				}

				if (property == "indices" || property == "index")
				{
					indices = JsonSerializer.Deserialize<IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.IndicesPrivileges>?>(ref reader, options);
					continue;
				}

				if (property == "metadata")
				{
					metadata = JsonSerializer.Deserialize<IReadOnlyDictionary<string, object>?>(ref reader, options);
					continue;
				}

				if (property == "name")
				{
					name = JsonSerializer.Deserialize<string>(ref reader, options);
					continue;
				}

				if (property == "run_as")
				{
					runAs = JsonSerializer.Deserialize<IReadOnlyCollection<string>?>(ref reader, options);
					continue;
				}

				if (property == "_sort")
				{
					sort = JsonSerializer.Deserialize<IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.FieldValue>?>(ref reader, options);
					continue;
				}

				if (property == "transient_metadata")
				{
					transientMetadata = JsonSerializer.Deserialize<IReadOnlyDictionary<string, object>?>(ref reader, options);
					continue;
				}
			}
		}

		return new QueryRole { Applications = applications, Cluster = cluster, Description = description, Indices = indices, Metadata = metadata, Name = name, RunAs = runAs, Sort = sort, TransientMetadata = transientMetadata };
	}

	public override void Write(Utf8JsonWriter writer, QueryRole value, JsonSerializerOptions options)
	{
		throw new NotImplementedException("'QueryRole' is a readonly type, used only on responses and does not support being written to JSON.");
	}
}

[JsonConverter(typeof(QueryRoleConverter))]
public sealed partial class QueryRole
{
	/// <summary>
	/// <para>
	/// A list of application privilege entries
	/// </para>
	/// </summary>
	public IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.ApplicationPrivileges>? Applications { get; init; }

	/// <summary>
	/// <para>
	/// A list of cluster privileges. These privileges define the cluster level actions that API keys are able to execute.
	/// </para>
	/// </summary>
	public IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.ClusterPrivilege>? Cluster { get; init; }

	/// <summary>
	/// <para>
	/// Optional description of the role descriptor
	/// </para>
	/// </summary>
	public string? Description { get; init; }

	/// <summary>
	/// <para>
	/// A list of indices permissions entries.
	/// </para>
	/// </summary>
	public IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.Security.IndicesPrivileges>? Indices { get; init; }

	/// <summary>
	/// <para>
	/// Optional meta-data. Within the metadata object, keys that begin with <c>_</c> are reserved for system usage.
	/// </para>
	/// </summary>
	public IReadOnlyDictionary<string, object>? Metadata { get; init; }

	/// <summary>
	/// <para>
	/// Name of the role.
	/// </para>
	/// </summary>
	public string Name { get; init; }

	/// <summary>
	/// <para>
	/// A list of users that the API keys can impersonate. <em>Note</em>: in Serverless, the run-as feature is disabled. For API compatibility, you can still specify an empty <c>run_as</c> field, but a non-empty list will be rejected.
	/// </para>
	/// </summary>
	public IReadOnlyCollection<string>? RunAs { get; init; }
	public IReadOnlyCollection<Elastic.Clients.Elasticsearch.Serverless.FieldValue>? Sort { get; init; }
	public IReadOnlyDictionary<string, object>? TransientMetadata { get; init; }
}